/*
 * @Author: szx
 * @Date: 2022-03-15 19:25:37
 * @LastEditTime: 2022-03-15 20:06:43
 * @Description:
 * @FilePath: \learn\MDN_JS学习\八股文\事件分发器\事件分发器.js
 */
class EventEmitter {
    constructor() {
        this.handlers = {};
    }

    // 注册事件回调
    on(eventName, cb) {
        const handlers = this.handlers;

        if (!handlers[eventName]) {
            handlers[eventName] = [];
        }

        handlers[eventName].push(cb);
    }

    // 移除某个事件回调队列中的事件回调函数
    off(eventName, cb) {
        const callbacks = this.handlers[eventName];
        if (!callbacks) return;
        const idx = callbacks.indexOf(cb);
        if (idx !== -1) {
            callbacks.splice(idx, 1);
        }
    }

    // 触发某类事件中注册的所有回调
    emit(eventName, ...args) {
        const callbacks = this.handlers[eventName];

        if (callbacks) {
            // 对事件队列做一次浅拷贝，主要是防止 once 注册的回调在触发后对调用顺序造成影响
            const _callbacks = callbacks.slice();
            _callbacks.forEach((cb) => {
                cb(...args);
            });
        }
    }

    once(eventName, cb) {
        const wrappedCb = (...args) => {
            cb(...args);
            this.off(eventName, wrappedCb);
        };

        this.on(eventName, wrappedCb);
    }
}
const emi = new EventEmitter();
emi.on('nima', (arg1) => {
    console.log(arg1);
});
emi.once('nihao', (arg1) => {
    console.log('nihao', arg1);
});
setTimeout(() => {
    // emi.emit('nima', 'pokok');
    // console.log(emi);

    emi.emit('nihao', 'cdcd');
    emi.emit('nihao', '7777');
    emi.emit('nihao', '888');
}, 1000);
